/**
 * 时间处理工具类
 * 
 * @author suihonghua
 * 
 * @returns {DateUtil}
 */
function DateUtil() {
}
DateUtil.prototype = new Object();

// DateUtil.prototype.length = 1;

/**
 * 格式化日期时间
 * 
 * @param d
 *            Date实例
 * @returns string 格式如：2001-01-01 01:01:01
 * 
 * @author suihonghua
 */
DateUtil.formatDateTime = function(date) {
	return this.format(date, "yyyy-MM-dd HH:mm:ss");
};

/**
 * 格式化日期
 * 
 * @param d
 *            Date实例
 * @returns string 格式如：2001-01-01
 * 
 * @author suihonghua
 */
DateUtil.formatDate = function(date) {
	return this.format(date, "yyyy-MM-dd");
};


/**
 * 格式化日期
 * 
 * @param dateStr 
 *            可以是毫秒级或者字符串
 * @returns string 格式如：2001-01-01
 * 
 * @author suihonghua
 */
DateUtil.parseAndformatDate = function(dateStr) {
	return this.format(DateUtil.parse(dateStr), "yyyy-MM-dd");
};

/**
 * 格式化时间
 * 
 * @param d
 *            Date实例
 * @returns string 格式如：01:01:01
 * 
 * @author suihonghua
 */
DateUtil.formatTime = function(date) {
	return this.format(date, "HH:mm:ss");
};

/**
 * 时间格式化 e.g. var testDate = new Date( 1320336000000 );//这里必须是整数，毫秒
 * 
 * var testStr1 = DateUtil.format(testDate, "yyyy年MM月dd日HH小时mm分ss秒"); var
 * testStr2 = DateUtil.format(testDate, "yyyy-MM-dd HH:mm:ss.S"); var testStr3 =
 * DateUtil.format(testDate, "yyyy-MM-dd HH:mm:ss"); alert(testStr1);
 * alert(testStr2); alert(testStr3);
 * 
 * @param date
 * @param format
 * @returns
 * 
 * @author suihonghua
 */
DateUtil.format = function(date, format) {
	try {
		// yyyy年MM月dd日 HH小时mm分ss秒
		var o = {
			"M+" : date.getMonth() + 1, // month
			"d+" : date.getDate(), // day
			"H+" : date.getHours(), // hour
			"m+" : date.getMinutes(), // minute
			"s+" : date.getSeconds(), // second
			"q+" : Math.floor((date.getMonth() + 3) / 3), // quarter
			"S" : date.getMilliseconds()
		// millisecond
		};

		if (/(y+)/.test(format)) {
			format = format.replace(RegExp.$1, (date.getFullYear() + "")
					.substr(4 - RegExp.$1.length));
		}
		for ( var k in o) {
			if (new RegExp("(" + k + ")").test(format)) {
				format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k]
						: ("00" + o[k]).substr(("" + o[k]).length));
			}
		}
        return format;
	} catch (e) {
		return "";
	}
};

/**
 * 解析为Data类型(目前string只支持标准格式)
 * 
 * @param val
 *            参数(int or string)
 * @returns Date
 * 
 * @author suihonghua
 */
DateUtil.parse = function(val) {
	if (typeof (val) == "number") {
		return new Date(val);
	} else if (typeof (val) == "string") {
		return new Date(Date.parse(val.replace(/-/g, "/")));
	}
	return null;
};


//日期加上天数得到新的日期
//dateTemp 需要参加计算的日期，days要添加的天数，返回新的日期，日期格式：YYYY-MM-DD
DateUtil.getNewDay = function(dateTemp, days) {
	var nDate = DateUtil.parse(dateTemp, "yyyy-MM-dd"); //按照MM-DD-YYYY格式  转换
	var millSeconds = Math.abs(nDate) + (days * 24 * 60 * 60 * 1000);
	var rDate = new Date(millSeconds);
	return DateUtil.formatDate(rDate);
}

/**
* 比较日期大小
* @param startDateStr
* @param endDateStr
* @returns {Boolean}
*/
DateUtil.dateCompare = function(startDateStr, endDateStr) {
	var startDate = DateUtil.parse(startDateStr, "yyyy-MM-dd"); //按照MM-DD-YYYY格式  转换
	var startMillSeconds = Math.abs(startDate);
	
	var endDate = DateUtil.parse(endDateStr, "yyyy-MM-dd"); //按照MM-DD-YYYY格式  转换
	var endMillSeconds = Math.abs(endDate);
	if (startMillSeconds < endMillSeconds) {
		return false;
	}
	return true;
}


/**
* 比较日期大小
* @param startDateStr
* @returns {Boolean}
*/
DateUtil.dateCompareNow = function(startDateStr) {
	return this.dateCompare(startDateStr, DateUtil.formatDate(new Date()));
}

/**
 * 字符串工具类
 * 
 * @author suihonghua
 * 
 * @returns {StringUtil}
 * 
 */
function StringUtil() {
}
StringUtil.prototype = new Object();

// StringUtil.prototype.length = 1;

StringUtil.nullToEmpty = function(str) {
	return str == null ? "" : str;
};

StringUtil.isEmpty = function(str) {
	if (null == str || '' == str) {
		return true;
	}
	return false;
};

StringUtil.isNotEmpty = function(str) {
	return !StringUtil.isEmpty(str);
};

StringUtil.trim = function(str) {
	return str.replace(/(^[\s]*)|([\s]*$)/g, "");
};

StringUtil.trimLeft = function(str) {
	return str.replace(/(^[\s]*)/g, "");
};

StringUtil.trimRight = function(str) {
	return str.replace(/([\s]*$)/g, "");
};

StringUtil.replaceAll = function(str, s1, s2) {
	return str.replace(new RegExp(s1, "gm"), s2);
};

StringUtil.startWith = function(str, s) {
	if (str == null || s == '' || str.length == 0 || s.length == 0)
		return false;
	if (str.substr(0, s.length) == s)
		return true;
	else
		return false;
	return true;
};

Array.prototype.remove = function(s) {
    for (var i = 0; i < this.length; i++) {
        if (s == this[i])
            this.splice(i, 1);
    }
}

/**
 * Simple Map
 * 
 * 
 * var m = new Map();
 * m.put('key','value');
 * ...
 * var s = "";
 * m.each(function(key,value,index){
 *         s += index+":"+ key+"="+value+"\n";
 * });
 * alert(s);
 * 
 * @author dewitt
 * @date 2008-05-24
 */
function Map() {
    /** 存放键的数组(遍历用到) */
    this.keys = new Array();
    /** 存放数据 */
    this.data = new Object();
    
    /**
     * 放入一个键值对
     * @param {String} key
     * @param {Object} value
     */
    this.put = function(key, value) {
        if(this.data[key] == null){
            this.keys.push(key);
        }
        this.data[key] = value;
    };
    
    /**
     * 获取某键对应的值
     * @param {String} key
     * @return {Object} value
     */
    this.get = function(key) {
        return this.data[key];
    };
    
    /**
     * 删除一个键值对
     * @param {String} key
     */
    this.remove = function(key) {
        this.keys.remove(key);
        this.data[key] = null;
    };
    
    this.containsKey = function(key) {
    	var len = this.keys.length;
        for (var i = 0; i < len; i++) {
        	if (this.keys[i] == key) {
        		return true;
        	}
        }
        return false;
    }
    
    /**
     * 遍历Map,执行处理函数
     * 
     * @param {Function} 回调函数 function(key,value,index){..}
     */
    this.each = function(fn){
        if(typeof fn != 'function'){
            return;
        }
        var len = this.keys.length;
        for(var i=0;i<len;i++){
            var k = this.keys[i];
            fn(k,this.data[k],i);
        }
    };
    
    /**
     * 获取键值数组(类似Java的entrySet())
     * @return 键值对象{key,value}的数组
     */
    this.entrys = function() {
        var len = this.keys.length;
        var entrys = new Array(len);
        for (var i = 0; i < len; i++) {
            entrys[i] = {
                key : this.keys[i],
                value : this.data[i]
            };
        }
        return entrys;
    };
    
    /**
     * 判断Map是否为空
     */
    this.isEmpty = function() {
        return this.keys.length == 0;
    };
    
    /**
     * 获取键值对数量
     */
    this.size = function(){
        return this.keys.length;
    };
    
    /**
     * 重写toString 
     */
    this.toString = function(){
        var s = "{";
        for(var i=0;i<this.keys.length;i++,s+=','){
            var k = this.keys[i];
            s += k+"="+this.data[k];
        }
        s+="}";
        return s;
    };
}


function FileUtil() {
}
FileUtil.prototype = new Object();

function FileObj(id, filename, url, bigUrl, fullUrl) {
	this.id = id;
	this.filename = filename;
	this.url = url;
	this.bigUrl = bigUrl;
	this.fullUrl = fullUrl;
}

//http://172.16.1.165/partner/pdf/20160620193801269_serverStartup.pdf?id=1110&filename=serverStartup.pdf
FileUtil.convObj = function(url) {
	if (url == null || url == '' || url == 'null' || url == 'undefined') {
		return;
	}
	var url = '' + url;
	var _whIndex = url.indexOf("?");
	if (_whIndex == -1) {
		return new FileObj(-1, "", url, url, url);
	}
	var _link = url.substring(0, _whIndex);
	var _id, _filename, _bigUrl;
	if (StringUtil.isNotEmpty(url.substring(_whIndex + 1))) {
		var _paramStrs = url.substring(_whIndex + 1).split("&");
		for (var i = 0; i < _paramStrs.length; i++) {
			var _tempArrays = _paramStrs[i].split("=");
			if (_tempArrays != null && _tempArrays.length > 1) {
				if ("id" == _tempArrays[0]) {
					_id = _tempArrays[1];
				} else if ("filename" == _tempArrays[0]) {
					_filename = _tempArrays[1];
				} else if ("big" == _tempArrays[0]) {
					_bigUrl = _link.substring(0, _link.lastIndexOf("/")) + "/" + _tempArrays[1];
				}
			}
		}
	}
	return new FileObj(_id, _filename, _link, _bigUrl, url);
}

//http://172.16.1.165/partner/pdf/20160620193801269_serverStartup.pdf?id=1110&filename=serverStartup.pdf,http://172.16.1.165/partner/pdf/20160620193802809_sysamug.pdf?id=1111&filename=sysamug.pdf,http://172.16.1.165/partner/pdf/20160620193803128_requestProcess.pdf?id=1112&filename=requestProcess.pdf
FileUtil.convList = function(fullUrl) {
	if (fullUrl == null || fullUrl == '' || fullUrl == 'null' || fullUrl == 'undefined') {
		return;
	}
	var fullUrl = '' + fullUrl;
	var urls = fullUrl.split(",");
	var _result = new Array();
	for (var i = 0; i < urls.length; i++) {
		_result[i] = FileUtil.convObj(urls[i]);
	}
	return _result;
}


/**
 * 正则验证工具类
 * 
 * @author ligang
 * 
 * @returns {RegexUtil}
 */
function RegexUtil() {
}
RegexUtil.prototype = new Object();

/**
 * 验证参数是否是有效URL
 * 
 * @param url
 * @return
 */
RegexUtil.isUrl = function(url) {
	var strRegex = "^((https|http|ftp|rtsp|mms)://)?([a-z0-9A-Z]{0,10}\.)?[a-z0-9A-Z][a-z0-9A-Z]{0,61}?[a-z0-9A-Z]\.com|net|cn|cc (:s[0-9]{1-4})?/$";
	var re = new RegExp(strRegex);
	if (re.test(url)) {
		return true;
	} else {
		return false;
	}
};
/**
 * 根据名称判断是否是直辖市
 * @param name
 * @returns {boolean}
 */
RegexUtil.isMunicipality = function(name){
    var strRegex = /^(北京|上海|天津|重庆)/;
    if(strRegex.test(name)) {
        return true;
    } else {
        return false;
    }
};
/**
 * 校验是否是数字或带小数点数字
 * @param name
 * @returns {boolean}
 */
RegexUtil.isNumber = function(name){
    var strRegex = /^(\d{1,8})(\.\d{1,2})?$/;
    if(strRegex.test(name)) {
        return true;
    } else {
        return false;
    }
};
/**
 * 校验是否正整数
 * @param name
 * @returns {boolean}
 */
RegexUtil.isInteger = function(name){
	var strRegex = /^\d+$/;
	if(strRegex.test(name)) {
		return true;
	} else {
		return false;
	}
};

/**序列化表单数据
 * @param	formId  form表单的Id值
 */
function serializeForm(formId) {
    var jsonData = {};
    var serializeArray = $("#" + formId).serializeArray();
    $.each(serializeArray, function(index, field){
        var name = field.name;
        var value = StringUtil.trim(field.value);
        if(value){
            jsonData[name] = value;
        }
    });
    return jsonData;
}

// 除法函数，用来得到精确的除法结果
// 说明：javascript的除法结果会有误差，在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
// 调用：accDiv(arg1,arg2)
// 返回值：arg1除以arg2的精确结果
function accDiv(arg1, arg2) {
	var  r1 = 0,  r2 = 0, t1, t2, n, m;
	try {
		r1 = arg1.toString().split(".")[1].length;
	} catch (e) {
        r1 = 0;
	}
	try {
		r2 = arg2.toString().split(".")[1].length;
	} catch (e) {
        r2 = 0;
	}
	// 动态控制精度长度
	n = (r1 >= r2) ? r1 : r2;
    //m = (r1 >= r2) ? r1-r2 : r2-r1;
	with (Math) {
		t1 = Number(arg1.toString().replace(".", ""));
		t2 = Number(arg2.toString().replace(".", ""));
		return ((t1 / t2) * pow(10, r2-r1)).toFixed(n<2?2:n);
	}
}

// 给Number类型增加一个div方法，调用起来更加方便。
Number.prototype.div = function(arg) {
	return accDiv(this, arg);
};


//说明：javascript的乘法结果会有误差，在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用：accMul(arg1,arg2)
//返回值：arg1乘以arg2的精确结果
function accMul(arg1,arg2)
{
    var r1, r2, m, n;
    var m=0,s1=arg1.toString(),s2=arg2.toString();
    try{
        r1=s1.split(".")[1].length;
    }catch(e){
        r1 = 0;
    }
    try{
        r2=s2.split(".")[1].length;
    }catch(e){
        r2 = 0;
    }
    // 动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    m = r1 + r2;
    return (Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10, m)).toFixed(n);

}
//给Number类型增加一个mul方法，调用起来更加方便。
Number.prototype.mul = function (arg){
    return accMul(arg, this);
};

function accMulThree(arg1,arg2,arg3)
{
  var r1, r2, r3, m;
  var m=0,s1=arg1.toString(),s2=arg2.toString(),s3=arg3.toString();
  try{
      r1=s1.split(".")[1].length;
  }catch(e){
      r1 = 0;
  }
  try{
      r2=s2.split(".")[1].length;
  }catch(e){
      r2 = 0;
  }
  try{
      r3=s3.split(".")[1].length;
  }catch(e){
      r3 = 0;
  }  
  // 精度固定2位
  m = r1 + r2 + r3;
  return (Number(s1.replace(".",""))*Number(s2.replace(".",""))*Number(s3.replace(".",""))/Math.pow(10, m)).toFixed(2);

}

// 加法函数，用来得到精确的加法结果
// 说明：javascript的加法结果会有误差，在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
// 调用：accAdd(arg1,arg2)
// 返回值：arg1加上arg2的精确结果
function accAdd(arg1, arg2) {
	var r1, r2, m, n;
	try {
		r1 = arg1.toString().split(".")[1].length;
	} catch (e) {
		r1 = 0;
	}
	try {
		r2 = arg2.toString().split(".")[1].length;
	} catch (e) {
		r2 = 0;
	}
	m = Math.pow(10, Math.max(r1, r2));
	// 动态控制精度长度
	n = (r1 >= r2) ? r1 : r2;
	return ((arg1 * m + arg2 * m) / m).toFixed(n);
}

// 给Number类型增加一个add方法，调用起来更加方便。
Number.prototype.add = function(arg) {
	return accAdd(arg, this);
};
// 减法函数
function accSub(arg1, arg2) {
	var r1, r2, m, n;
	try {
		r1 = arg1.toString().split(".")[1].length;
	} catch (e) {
		r1 = 0;
	}
	try {
		r2 = arg2.toString().split(".")[1].length;
	} catch (e) {
		r2 = 0;
	}
	m = Math.pow(10, Math.max(r1, r2));
	// last modify by deeka
	// 动态控制精度长度
	n = (r1 >= r2) ? r1 : r2;
	return ((arg2 * m - arg1 * m) / m).toFixed(n);
}
// /给number类增加一个sub方法，调用起来更加方便
Number.prototype.sub = function(arg) {
	return accSub(arg, this);
};
